package cn.touna.jss.common.util;

import cn.touna.jss.common.properties.disconf.OssClientProperties;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.utils.IOUtils;
import com.aliyun.oss.model.*;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.List;

/***
 **************************************************************
 * 阿里云OSS文件上传工具类
 * @Author  zhangjialian
 * @Date    2018/9/3 11:11
 * @Version V1.0
 *************************************************************/
@Component
public class OssClientUtil {
    private static final Logger logger = LogManager.getLogger(OssClientUtil.class);
   @Autowired
   private OssClientProperties ossClientProperties;

    /**
     ********************************************************************
     * OSS文件上传
     * @param key key要以/结尾
     * @param file 上传文件对象
     * @Author  zhangjialian
     * @return  void
     * @date    2018/9/3 11:05
     ********************************************************************/
    public void uploadFile(String key,File file) throws Throwable {
        logger.info("aliyuncs uploadFile,endpoint={},accessKeyId={},accessKeySecret={}", new Object[]{ossClientProperties.getEndpoint(),ossClientProperties.getAccessKeyId(),ossClientProperties.getAccessKeySecret()});
        OSS ossClient = new OSSClientBuilder().build(ossClientProperties.getEndpoint(),ossClientProperties.getAccessKeyId(),ossClientProperties.getAccessKeySecret());
        uploadFile(ossClient,ossClientProperties.getBucketName(),key, org.apache.commons.io.FileUtils.readFileToByteArray(file));
    }

    /**
     ********************************************************************
     * OSS文件byte[]上传
     * @param key 存放Oss文件key
     * @param file byte文件流
     * @Author  zhangjialian
     * @return  void
     * @date    2018/9/3 11:05
     ********************************************************************/
    public void uploadFile(String key,byte[] file) throws Throwable {
        logger.info("aliyuncs uploadFile,endpoint={},accessKeyId={},accessKeySecret={}", new Object[]{ossClientProperties.getEndpoint(),ossClientProperties.getAccessKeyId(),ossClientProperties.getAccessKeySecret()});
        OSS ossClient = new OSSClientBuilder().build(ossClientProperties.getEndpoint(),ossClientProperties.getAccessKeyId(),ossClientProperties.getAccessKeySecret());
        uploadFile(ossClient,ossClientProperties.getBucketName(),key,file);
    }

    public byte[] getBytesFromOss(String fileKey) throws Throwable{
        logger.info("aliyuncs uploadFile,endpoint={},accessKeyId={},accessKeySecret={}", new Object[]{ossClientProperties.getEndpoint(),ossClientProperties.getAccessKeyId(),ossClientProperties.getAccessKeySecret()});
        OSS ossClient = new OSSClientBuilder().build(ossClientProperties.getEndpoint(),ossClientProperties.getAccessKeyId(),ossClientProperties.getAccessKeySecret());
        return getOSSBytes(ossClient,ossClientProperties.getBucketName(),fileKey);
    }

    /**
     ********************************************************************
     * OSS文件断点本地下载
     * @param fileKey 存放Oss文件key
     * @param filePath 目标下载路径
     * @param fileName 文件名
     * @Author  zhangjialian
     * @return  void
     * @date    2018/9/3 11:04
     ********************************************************************/
    public void downloadFile(String fileKey,String filePath,String fileName) throws Throwable {
        logger.info("aliyuncs downloadFile,endpoint={},accessKeyId={},accessKeySecret={}", new Object[]{ossClientProperties.getEndpoint(),ossClientProperties.getAccessKeyId(),ossClientProperties.getAccessKeySecret()});
        OSS ossClient = new OSSClientBuilder().build(ossClientProperties.getEndpoint(),ossClientProperties.getAccessKeyId(),ossClientProperties.getAccessKeySecret());
        downloadFile(ossClient,ossClientProperties.getBucketName(),fileKey,filePath,fileName);
    }
   /**
    ********************************************************************
    * 查看Bucket中的Object
    * @param filePrefix 文件名前缀
    * @param maxSize 查询最大个数
    * @Author  zhangjialian
    * @return  java.utils.List<com.aliyun.oss.model.OSSObjectSummary>
    * @date    2018/9/7 17:21
    ********************************************************************/
    public List<OSSObjectSummary> listObjects(String filePrefix,int maxSize) throws Throwable {
        logger.info("aliyuncs listObjects,endpoint={},accessKeyId={},accessKeySecret={}", new Object[]{ossClientProperties.getEndpoint(),ossClientProperties.getAccessKeyId(),ossClientProperties.getAccessKeySecret()});
        OSS ossClient = new OSSClientBuilder().build(ossClientProperties.getEndpoint(),ossClientProperties.getAccessKeyId(),ossClientProperties.getAccessKeySecret());
        ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest(ossClientProperties.getBucketName()).
                withMaxKeys(maxSize).withPrefix(filePrefix));
        if(objectListing==null) {return null;}
        return objectListing.getObjectSummaries();
    }
    /**
     ********************************************************************
     * 删除文件
     * @param filePrefix
     * @Author  zhangjialian
     * @return  boolean
     * @date    2018/9/7 17:35
     ********************************************************************/
    public boolean deleteFile(String filePrefix){
        OSS ossClient = new OSSClientBuilder().build(ossClientProperties.getEndpoint(),ossClientProperties.getAccessKeyId(),ossClientProperties.getAccessKeySecret());
        return deleteFile(ossClient,ossClientProperties.getBucketName(),filePrefix);
    }


    /*=============================静态工具方法=======================================*/
    /**
     ********************************************************************
     * OSS文件断点续传下载静态类
     * @param ossClient ossClient对象
     * @param bucketName bucketName名称
     * @param fileKey 文件key值
     * @param filePath 文件地址
     * @param fileName 文件名
     * @Author  zhangjialian
     * @return  com.aliyun.oss.model.ObjectMetadata
     * @date    2018/9/7 17:32
     ********************************************************************/
    public static ObjectMetadata downloadFile(OSS ossClient,String bucketName,String fileKey,String filePath,String fileName) throws Throwable {
        File fileDir = new File(filePath);
        //如果不存在 则创建
        if (!fileDir.exists()) {
            fileDir.mkdirs();
        }
        DownloadFileRequest downloadFileRequest = new DownloadFileRequest(bucketName, fileKey);
        // Sets the local file to download to
        downloadFileRequest.setDownloadFile(filePath + fileName);
        // Sets the concurrent task thread count 5. By default it's 1.
        downloadFileRequest.setTaskNum(5);
        // Sets the part size, by default it's 100K.
        downloadFileRequest.setPartSize(1024 * 1024 * 1);
        // Enable checkpoint. By default it's false.
        downloadFileRequest.setEnableCheckpoint(true);

        try {
            DownloadFileResult downloadResult = ossClient.downloadFile(downloadFileRequest);
            ObjectMetadata objectMetadata=downloadResult.getObjectMetadata();
            logger.info("aliyuncs downloadFile,result={}", new Object[]{objectMetadata});
            return downloadResult.getObjectMetadata();
        } finally {
            if(null != ossClient){
                ossClient.shutdown();
            }
        }
    }

    /**
     ********************************************************************
     * 根据key获取OSS服务器上的文件输入流
     * @param client OSS客户端
     * @param bucketName bucket名称
     * @param diskName 文件路径
     * @param fileKey Bucket下的文件的路径名+文件名
     * @Author  zhangjialian
     * @return  byte[]
     * @date    2018/9/7 17:44
     ********************************************************************/
    public static final byte[] getOSSBytes(OSS ossClient, String bucketName, String fileKey) throws Exception{
        try {
            OSSObject ossObj = ossClient.getObject(bucketName, fileKey);
            return IOUtils.readStreamAsByteArray(ossObj.getObjectContent());
        } finally {
            ossClient.shutdown();
        }

    }

    /**
     ********************************************************************
     * OSS文件上传静态类
     * @param ossClient
     * @param bucketName
     * @param fileKey
     * @param file
     * @Author  zhangjialian
     * @return  com.aliyun.oss.model.PutObjectResult
     * @date    2018/9/7 17:40
     ********************************************************************/
    public static PutObjectResult uploadFile(OSS ossClient, String bucketName, String fileKey, byte[] file) throws Throwable {
        try {
            PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileKey, new ByteArrayInputStream(file));
            PutObjectResult result=ossClient.putObject(putObjectRequest);
            logger.info("aliyuncs uploadFile,result={}", new Object[]{result});
            return result;
        } finally {
            if(null != ossClient){
                ossClient.shutdown();
            }
        }
    }

    /**
     ********************************************************************
     * @MethodName: deleteFile
     * @Description: 单文件删除
     * @param ossClient ossClient对象
     * @param fileKey 需要删除的文件名称
     * @Author  zhangjialian
     * @return boolean
     * @date    2018/9/7 17:27
     ********************************************************************/
    public static boolean deleteFile(OSS ossClient,String bucketName,String fileKey){
        try {
            GenericRequest request = new DeleteObjectsRequest(bucketName).withKey(fileKey);
            ossClient.deleteObject(request);
        } catch (Exception oe) {
            oe.printStackTrace();
            return false;
        } finally {
            ossClient.shutdown();
        }
        return true;
    }

    public static String getKey(String method,String reqNo,String fileType,String queryTime) {
        StringBuffer buffer=new StringBuffer();
        buffer.append(method + "_" + reqNo+"_"+fileType);
        if(StringUtils.isNotEmpty(queryTime)){
            buffer.append("."+queryTime);
        }
        return buffer.toString();
    }


    public static void main(String[] args) throws Throwable {
        String endpoint="http://oss-cn-szfinance.aliyuncs.com";
        String accessKeyId="LTAI4My5D4y9vnCU";
        String accessKeySecret="Nkmn060gZBlu6f3RFC1bbEcnmDUIZj";
        String bucketName="touna-test";
        //String key=getKey("tencent.iccardRecognize","123456","img",null);
        String key="tencent.ocr.recognize";
        File file=new File("D:/tmp/my.jpg");
        OSS ossClient = new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
//        ObjectListing objectListing = ossClient.listObjects(new ListObjectsRequest(bucketName).withMaxKeys(1000).withPrefix(key)
//                );
//        List<OSSObjectSummary> objectSummary = objectListing.getObjectSummaries();
//        System.out.println("summary:"+objectSummary.size());
//        System.out.println("您有以下Object：");
//        for (OSSObjectSummary object : objectSummary) {
//            System.out.println("\t" + object.getKey()+"\t"+object.getETag()+",:"+object.getSize());
//        }

//         byte[] by=getOSSBytes(ossClient,bucketName,"tencent.ocr.recognize_2059c8cb87852c9654bfdcf5858ebc37_img");
//         if(in!=null){
//             FileUtils.writeByteArrayToFile(new File("D:/tmp/haaaa.jpg"),by);
//         }

//        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, new ByteArrayInputStream("hello world".getBytes()));
//        PutObjectResult result=ossClient.putObject(putObjectRequest);
//        System.out.println(result.getETag());
//        PutObjectResult result=uploadFile(ossClient,bucketName,key,file);
//        System.out.println("上传是否成功:"+result.getETag());
//        if(result.getResponse()!=null){
//
//            System.out.println("上传是否成功:"+result.getResponse().isSuccessful());
//            System.out.println("上传响应信息:"+result.getResponse().toString());
//        }

        //downloadFile(ossClient,bucketName,"city.csv_20180903151925/","D:/tmp/","data.csv");
    }
}
